package com.wx.md.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.wx.md.common.Constant;
import com.wx.md.common.RedisService;
import com.wx.md.config.TokenConfig;
import com.wx.md.dao.SysUserDao;
import com.wx.md.dao.SysUserRoleDao;
import com.wx.md.enums.ResponseCode;
import com.wx.md.exception.BusinessException;
import com.wx.md.tb.SysUser;
import com.wx.md.service.LoginService;
import com.wx.md.service.SysPermissionService;
import com.wx.md.utils.JwtTokenUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.apache.shiro.subject.Subject;

import java.util.HashMap;
import java.util.List;

@Service("loginService")
public class LoginServiceImpl implements LoginService {

    @Autowired
    SysUserDao sysUserDao;
    @Autowired
    SysUserRoleDao sysUserRoleDao;

    @Autowired
    SysPermissionService sysPermissionService;
    @Autowired
    RedisService redisService;
    @Autowired
    private TokenConfig tokenConfig;

    @Override
    public R login(SysUser sysUser) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_name", sysUser.getUserName());
        List<SysUser> sysUserList = sysUserDao.selectList(queryWrapper);
        if (sysUserList.size() <= 0) {// 账号不存在
            throw new BusinessException(ResponseCode.ACCOUNT_ERROR);
        }
        SysUser sysUserDb = sysUserList.get(0);
        if (!BCrypt.checkpw(sysUser.getPassword(), sysUserDb.getPassword())) {// 密码不正确
            throw new BusinessException(ResponseCode.ACCOUNT_PASSWORD_ERROR);
        }
        if (sysUserDb.getStatus() == 2) {// 账号锁定
            return R.failed(ResponseCode.ACCOUNT_LOCK);
        }
        // 通过用户id获取该用户所拥有的角色名称
        List<String> roleNames = sysUserRoleDao.getRoleNameByUserId(sysUserDb.getId());
        // 通过用户id获取该用户所拥有的权限授权 如：sys:user:add
        List<String> permissionPerms = sysUserRoleDao.getPermissionPermsByUserId(sysUserDb.getId());

        // 用户业务 token 令牌
        String accessToken = JwtTokenUtil.getInstance()
                .setIssuer(tokenConfig.getIssuer())
                .setSecret(tokenConfig.getSecretKey())
                .setExpired(tokenConfig.getAccessTokenExpireTime().toMillis())
                .setSubObject(sysUserDb.getId())
                .setClaim(Constant.JWT_ROLES_KEY, JSON.toJSONString(roleNames))
                //.setClaim(Constant.JWT_PERMISSIONS_KEY, JSON.toJSONString(permissionPerms))
                //.setClaim(Constant.JWT_USER_NAME, sysUserDb.getUserName())
                .generateToken();
        // 每次登录的时候吧token放到 redis，用于只能一个账号同时在线
        redisService.set(Constant.JWT_USER_NAME + sysUserDb.getId(), accessToken);
        // 每次登录先删除需要重新登录的标记
        redisService.delete(Constant.JWT_USER_LOGIN_BLACKLIST+sysUserDb.getId());
        HashMap resultMap = new HashMap();
        resultMap.put("token", accessToken);
        return R.ok(resultMap);
    }


    public static void main(String[] args) {
        System.out.println(BCrypt.hashpw("111111", BCrypt.gensalt()));
    }

    @Override
    public SysUser info(String token) {
        String userId = JwtTokenUtil.getInstance().getUserId(token);
        SysUser sysUser = sysUserDao.selectById(userId);
        if(sysUser==null){
            throw new BusinessException(ResponseCode.TOKEN_PAST_DUE);
        }
        // 通过用户id获取该用户所拥有的角色名称
        List<String> roleNames = sysUserRoleDao.getRoleNameByUserId(userId);
        sysUser.setRoles(roleNames);
        return sysUser;
    }

    @Override
    public void logout(String token) {
        if (StringUtils.isBlank(token)){
            throw new BusinessException(ResponseCode.DATA_ERROR);
        }
        // shiro 退出
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()){
            subject.logout();
        }
        // 获取用户 id
        String userId = JwtTokenUtil.getInstance().getUserId(token);
        // 每次退出登录先删除需要重新登录的标记
        redisService.delete(Constant.JWT_USER_LOGIN_BLACKLIST+userId);
        /**
         * 清楚用户授权数据缓存
         */
        redisService.delete(Constant.IDENTIFY_CACHE_KEY+userId);
    }


    //    @Override
//    public R<LoginRespVo> login(LoginReqVo loginReqVo) {
//        QueryWrapper queryWrapper = new QueryWrapper();
//        queryWrapper.eq("user_name",loginReqVo.getUsername());
//        List<SysUser> selectList = sysUserDao.selectList(queryWrapper);
//        if (selectList.size() <=0){// 账号不存在
//            throw new BusinessException(ResponseCode.ACCOUNT_ERROR);
//        }
//        SysUser sysUser = selectList.get(0);
//        if (!BCrypt.checkpw(loginReqVo.getPassword(),sysUser.getPassword())){// 密码不正确
//            throw new BusinessException(ResponseCode.ACCOUNT_PASSWORD_ERROR);
//        }
//        if (sysUser.getStatus() == 2){// 账号锁定
//            return R.failed(ResponseCode.ACCOUNT_LOCK.getMessage());
//        }
//        // 查询用户拥有的权限菜单列表
//        List<PermissionRespNodeVo> permissionRespNodeVos = sysPermissionService.permissionTreeListByUserId(sysUser.getId());
//
//        // 查询前端按钮权限
//        List<String> permissionCodes = sysUserRoleDao.getPermissionCodesByUserId(sysUser.getId());
//        // 通过用户id获取该用户所拥有的角色名称
//        List<String> roleNames = sysUserRoleDao.getRoleNameByUserId(sysUser.getId());
//        // 通过用户id获取该用户所拥有的权限授权 如：sys:user:add
//        List<String> permissionPerms = sysUserRoleDao.getPermissionPermsByUserId(sysUser.getId());
//
//        // 用户业务 token 令牌
//        String accessToken = JwtTokenUtil.getInstance()
//                .setIssuer(tokenConfig.getIssuer())
//                .setSecret(tokenConfig.getSecretKey())
//                .setExpired(tokenConfig.getAccessTokenExpireTime().toMillis())
//                .setSubObject(sysUser.getId())
//                .setClaim(Constant.JWT_ROLES_KEY, JSON.toJSONString(roleNames))
//                .setClaim(Constant.JWT_PERMISSIONS_KEY, JSON.toJSONString(permissionPerms))
//                .setClaim(Constant.JWT_USER_NAME, sysUser.getUserName())
//                .generateToken();
//        // 每次登录的时候吧token放到 redis，用于只能一个账号同时在线
//        redisService.set(Constant.JWT_USER_NAME+sysUser.getId(),accessToken);
//        // 每次登录先删除需要重新登录的标记
//        redisService.delete(Constant.JWT_USER_LOGIN_BLACKLIST+sysUser.getId());
//        LoginRespVo loginRespVo = new LoginRespVo();
//        loginRespVo.setAccessToken(accessToken);
//        loginRespVo.setId(sysUser.getId());
//        loginRespVo.setPhone(sysUser.getPhone());
//        loginRespVo.setUsername(sysUser.getUserName());
//        loginRespVo.setNickname(sysUser.getNickName());
//        loginRespVo.setMenus(permissionRespNodeVos);
//        loginRespVo.setPermissions(permissionCodes);
//        return R.ok(loginRespVo);
//    }
}
